﻿using System;
using System.Collections.Generic;

namespace smp.ButterflyCakes.Models.ViewModels.Order
{
    public class PotentialSizesView
    {
        private readonly double _maxMultiplier = 1.5;

        public PotentialSizesView(int requiredPortions, PortionType portionType, bool isCarved)
        {
            Round = new List<PortionSize>();
            Square = new List<PortionSize>();
            Rectangle = new List<PortionSize>();
            PortionType = portionType;
            CalculateSizes(requiredPortions);
            if (isCarved)
                _maxMultiplier = 2;
        }

        public PortionType PortionType { get; private set; }
        public List<PortionSize> Round { get; private set; }
        public List<PortionSize> Square { get; private set; }
        public List<PortionSize> Rectangle { get; private set; }

        private void CalculateSizes(int requiredPortions)
        {
            for(var i = 3; i <  12; i++)
            {
                ProcessRound(i, requiredPortions);
                ProcessSquare(i, requiredPortions);
                for(var j = 3; j < 12; j++)
                {
                    ProcessRectable(i, j, requiredPortions);
                }
            }
        }

        private void ProcessRound(int diameter, int requiredPortions)
        {
            var surfaceArea = diameter*3.14;
            var portions = PortionType == PortionType.Party
                           ? (int) Math.Floor(surfaceArea)
                           : (int) (Math.Floor(surfaceArea/2));
            if (portions >= requiredPortions && portions < (requiredPortions * _maxMultiplier))
            {
                Round.Add(new PortionSize(portions, CakeShape.Round, diameter, 0, requiredPortions));
            }
        }

        private void ProcessSquare(int size, int requiredPortions)
        {
            double surfaceArea = size*size;
            var portions = PortionType == PortionType.Party
                           ? (int)Math.Floor(surfaceArea)
                           : (int)(Math.Floor(surfaceArea / 2));
            if (portions >= requiredPortions && portions < (requiredPortions * _maxMultiplier))
            {
                Square.Add(new PortionSize(portions, CakeShape.Square, size, 0, requiredPortions));
            }
        }

        private void ProcessRectable(int length, int width, int requiredPortions)
        {
            if(length == width)
                return;
            double surfaceArea = length * width;
            var portions = PortionType == PortionType.Party
                           ? (int)Math.Floor(surfaceArea)
                           : (int)(Math.Floor(surfaceArea / 2));
            if (portions >= requiredPortions && portions < (requiredPortions * _maxMultiplier))
            {
                if(Rectangle.Find(x => x.Width == length && x.Size == width) != null)
                    return;
                Rectangle.Add(new PortionSize(portions, CakeShape.Rectangle, length, width, requiredPortions));
            }
        }
    }

    public enum PortionType
    {
        Party,
        Wedding
    }

    public class PortionSize
    {
        public PortionSize(int portions, CakeShape shape, int size, int width, int requiredPortions)
        {
            Portions = portions;
            Shape = shape;
            Size = size;
            Width = width;
            //double percentDifference = ((portions - requiredPortions)/portions)*100;
            //Excess = (int)Math.Ceiling(percentDifference);
        }

        public int Portions { get; set; }
        public CakeShape Shape { get; set; }
        public int Size { get; set; }
        public int Width { get; set; }
        public int Excess { get; set; }
    }
}
